package com.xyf.sys.service.impl;

import cn.hutool.core.util.IdUtil;
import com.xyf.sys.config.CustomException;
import com.xyf.sys.domain.*;
import com.xyf.sys.mapper.*;
import com.xyf.sys.service.*;
import com.xyf.sys.vo.UserListRequestVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author R-H
 * @Date 2024/12/41426
 * @Description
 */
@Slf4j
@Service
public class DeptServiceImpl implements IDeptService {

    @Autowired
    private DeptMapper mapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private UserPrinterMapper userPrinterMapper;
    @Autowired
    private IUserLogisticService userLogisticService;
    @Autowired
    private ISysPriceSchemeService priceSchemeService;
    @Autowired
    private IDictDataService dictDataService;
    @Autowired
    private IDeliveryService deliveryService;
    @Autowired
    private IGoodsService goodsService;

    @Override
    public Dept get(Long deptId) {
        return mapper.selectByPrimaryKey(deptId);
    }

    @Override
    public List<Dept> getList(String keyword, String userId) {
        List<Dept> depts = mapper.selectList(keyword);
        if (CollectionUtils.isEmpty(depts)){
            return new ArrayList<>();
        }
        List<Dept> deptList = new ArrayList<>(200);
        List<Dept> data = new ArrayList<>(200);
        depts.stream().forEach(dept -> {
            String[] ids = dept.getAncestors().split(",");
            for (String id : ids) {
                if (!id.equals("0")){
                    data.add(mapper.selectByPrimaryKey(Long.valueOf(id)));
                }
            }
        });
        deptList.addAll(data);
        // 去重逻辑
        deptList = deptList.stream()
                .filter(Objects::nonNull)
                .collect(Collectors.groupingBy(
                        Dept::getDeptId,
                        Collectors.reducing(null, (d1, d2) -> d1 != null ? d1 : d2)
                ))
                .values()
                .stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        deptList.stream().forEach(dept -> {
            List<UserRole> roleList = userRoleMapper.selectRole(dept.getDeptId());
            List<Role> roles = new ArrayList<>();
            if (roleList != null) {
                for (UserRole userRole : roleList) {
                    Role role = roleMapper.selectByPrimaryKey(userRole.getRoleId());
                    roles.add(role);
                }
            }
            dept.setRoles(roles);
        });
        return buildTree(deptList);
    }

    @Override
    public Dept add(Dept dept) {
        Dept record = mapper.selectByDeptName(dept.getDeptName(), "0");
        if (!Objects.isNull(record)) {
            throw new CustomException("此部门名称已存在");
        }
        dept.setDeptId(null);
        Dept pDept = mapper.selectByPrimaryKey(dept.getParentId());
        dept.setCreateBy(dept.getUserId());
        dept.setCreateTime(new Date());
        dept.setDelFlag("0");
        dept.setStatus("0");
        mapper.insert(dept);
        dept.setAncestors(pDept.getAncestors() + "," + dept.getDeptId());
        mapper.updateByPrimaryKeySelective(dept);
        return dept;
    }

    @Override
    public Dept update(Dept dept) {
        Dept record = mapper.selectByDeptName(dept.getDeptName(), "0");
        if (!Objects.isNull(record) && !record.getDeptId().equals(dept.getDeptId())) {
            throw new CustomException("此部门名称已存在");
        }
        dept.setUpdateBy(dept.getUserId());
        dept.setUpdateTime(new Date());
        mapper.updateByPrimaryKeySelective(dept);
        return dept;
    }

    @Override
    public int remove(Long deptId, String userId) {
        Dept dept = mapper.selectByPrimaryKey(deptId);
        List<Dept> childrenDeptList = mapper.selectByParentId(dept.getDeptId(), "0");
        if (!CollectionUtils.isEmpty(childrenDeptList)){
            throw new CustomException("存在在下级部门无法删除");
        }
        dept.setStatus("1");
        dept.setDelFlag("1");
        dept.setUpdateBy(dept.getUserId());
        dept.setUpdateTime(new Date());
        return mapper.updateByPrimaryKeySelective(dept);
    }

    @Override
    public Object getUserList(UserListRequestVo requestVo) {
        List<User> userList = userMapper.selectDeptUserList(requestVo);
        for (User user : userList) {
            List<UserRole> roleList = userRoleMapper.selectDeptRole(user.getId(), user.getDeptId());
            List<Role> roles = new ArrayList<>();
            if (roleList != null) {
                for (UserRole userRole : roleList) {
                    Role role = roleMapper.selectByPrimaryKey(userRole.getRoleId());
                    if ("USER".equals(role.getRoleKey())) {
                        continue;
                    }
                    roles.add(role);
                }
            }
            user.setRoles(roles);
        }
        return userList;
    }

    @Override
    public List<Dept> findRegimentDeptList(BigDecimal longitude, BigDecimal latitude, String keyword) {
        return mapper.selectNotEmptyUserDeptList("REGIMENT", longitude, latitude, keyword);
    }

    @Override
    public Object removeFollowUser(Long deptId, String userId, String uid) {
        User user = userMapper.selectByPrimaryKey(userId);
        user.setDeptId(null);
        user.setUpdateBy(uid);
        user.setUpdateTime(new Date());
        user.setLastUpdateTime(new Date());
        return userMapper.updateByPrimaryKey(user);
    }

    @Override
    public Dept queryInfo(Long deptId, String userId) {
        Dept dept = mapper.selectByPrimaryKey(deptId);
        if (dept == null){
            throw new CustomException("该部门不存在");
        }
        List<UserRole> roleList = userRoleMapper.selectDeptRole(userId, dept.getDeptId());
        List<UserPrinter> printers = userPrinterMapper.selectDeptPrinterList(dept.getDeptId());
        dept.setPrinters(printers);
        List<UserLogistic> logistics = userLogisticService.getList(dept.getDeptId());
        dept.setLogistics(logistics);
        dept.setLogisticPriceScheme(priceSchemeService.get(dept.getLogisticPriceSchemeId()));
        dept.setDryCleaningPriceScheme(priceSchemeService.get(dept.getDryCleaningPriceSchemeId()));
        String supplierTypeDictIds = dept.getSupplierTypeDictIds();
        if (StringUtils.isNotBlank(supplierTypeDictIds)) {
            List<DictData> supplierTypeList = new ArrayList<>(4);
            for (String code : supplierTypeDictIds.split(",")) {
                DictData dictData = dictDataService.get(Long.valueOf(code));
                supplierTypeList.add(dictData);
            }
            dept.setSupplierTypeList(supplierTypeList);
        }
        if (dept.getParentId() != 100L) {
            dept.setParentDeptInfo(this.get(dept.getParentId()));
        }
        List<Role> roles = new ArrayList<>();
        if (roleList != null) {
            for (UserRole userRole : roleList) {
                Role role = roleMapper.selectByPrimaryKey(userRole.getRoleId());
                if ("USER".equals(role.getRoleKey())) {
                    continue;
                }
                roles.add(role);
            }
        }
        dept.setRoles(roles);
        return dept;
    }

    @Override
    public Object edit(Dept body) {
        Dept dept = this.mapper.selectByPrimaryKey(body.getDeptId());
        if (StringUtils.isNotBlank(body.getMobile())){
            Dept record = mapper.selectByMobile(body.getMobile());
            if (record != null && !record.getDeptId().equals(dept.getDeptId())){
                throw new CustomException("该手机号已经注册，请更换手机号");
            }
        }
        if (body.getRoles_() != null) {
            userRoleMapper.deleteByDeptId(body.getDeptId());
            if (!CollectionUtils.isEmpty(body.getRoles_())) {
                for (Long roleId : body.getRoles_()) {
                    UserRole userRole = new UserRole();
                    userRole.setUserId(IdUtil.getSnowflakeNextIdStr());
                    userRole.setRoleId(roleId);
                    userRole.setDeptId(body.getDeptId());
                    userRoleMapper.insert(userRole);
                }
            }
        }
        if (body.getLogistics_() != null) {
            userLogisticService.delete(dept.getDeptId());
            if (!CollectionUtils.isEmpty(body.getLogistics_())) {
                for (Long logisticId : body.getLogistics_()) {
                    Delivery delivery = deliveryService.get(logisticId);
                    UserLogistic userLogistic = new UserLogistic();
                    userLogistic.setUserId(body.getUserId());
                    userLogistic.setDeptId(body.getDeptId());
                    userLogistic.setDeliveryName(delivery.getDeliveryName());
                    userLogistic.setDeliveryId(delivery.getDeliveryId());
                    userLogistic.setBizId(delivery.getBizid());
                    userLogistic.setPassword(delivery.getPassword());
                    userLogistic.setDictId(logisticId);
                    userLogistic.setType(delivery.getType());
                    userLogisticService.save(userLogistic);
                }
            }
        }
        if (body.getParentId() != null){
            Dept pDept = mapper.selectByPrimaryKey(body.getParentId());
            dept.setParentId(pDept.getDeptId());
            dept.setAncestors(pDept.getAncestors() + "," + dept.getDeptId());
        }
        if (StringUtils.isNotBlank(body.getMobile())) {
            dept.setMobile(body.getMobile());
        }
        if (StringUtils.isNotBlank(body.getAvatar())) {
            dept.setAvatar(body.getAvatar());
        }
        if (StringUtils.isNotBlank(body.getDeptName())) {
            dept.setDeptName(body.getDeptName());
        }
        if (StringUtils.isNotBlank(body.getName())) {
            dept.setName(body.getName());
        }
        if (StringUtils.isNotBlank(body.getRealName())) {
            dept.setRealName(body.getRealName());
        }
        if (StringUtils.isNotBlank(body.getRealId())) {
            dept.setRealId(body.getRealId());
        }
        if (StringUtils.isNotBlank(body.getProvince())) {
            dept.setProvince(body.getProvince());
        }
        if (StringUtils.isNotBlank(body.getCity())) {
            dept.setCity(body.getCity());
        }
        if (StringUtils.isNotBlank(body.getArea())) {
            dept.setArea(body.getArea());
        }
        if (StringUtils.isNotBlank(body.getAddress())) {
            dept.setAddress(body.getAddress());
        }
        if (StringUtils.isNotBlank(body.getLocationName())) {
            dept.setLocationName(body.getLocationName());
        }
        if (body.getLongitude() != null) {
            dept.setLongitude(body.getLongitude());
        }
        if (body.getLatitude() != null) {
            dept.setLatitude(body.getLatitude());
        }
        if (body.getLogisticPriceSchemeId() != null) {
            dept.setLogisticPriceSchemeId(body.getLogisticPriceSchemeId());
        }
        if (body.getDryCleaningPriceSchemeId() != null) {
            dept.setDryCleaningPriceSchemeId(body.getDryCleaningPriceSchemeId());
        }
        if (body.getMainDept() != null) {
            dept.setMainDept(body.getMainDept());
        }
        return this.update(dept);
    }

    @Override
    public List<Dept> search(String keyword) {
        List<Dept> depts = mapper.selectList(keyword);
        if (CollectionUtils.isEmpty(depts)){
            return null;
        }
        List<Dept> deptList = depts.stream().map(dept -> dept.getParentId())
                .filter(id -> !id.equals(0L))
                .collect(Collectors.toList())
                .stream()
                .map(pid -> mapper.selectByPrimaryKey(pid))
                .collect(Collectors.toList());
        deptList.addAll(depts);
        deptList.add(mapper.selectByPrimaryKey(100L));
        // 去重逻辑
        deptList = deptList.stream()
                .collect(Collectors.toMap(
                        Dept::getDeptId, // 以 deptId 作为键
                        dept -> dept,    // 值保持不变
                        (existing, replacement) -> existing // 如果键冲突，保留已有的值
                ))
                .values()
                .stream()
                .collect(Collectors.toList());
        deptList.stream().forEach(dept -> {
            List<UserRole> roleList = userRoleMapper.selectRole(dept.getDeptId());
            List<Role> roles = new ArrayList<>();
            if (roleList != null) {
                for (UserRole userRole : roleList) {
                    Role role = roleMapper.selectByPrimaryKey(userRole.getRoleId());
                    roles.add(role);
                }
            }
            dept.setRoles(roles);
        });
        return buildTree(deptList);
    }

    @Override
    public List<Dept> getRoleDept(String role) {
        List<Dept> depts = mapper.selectByRole(role);
        for (Dept dept : depts) {
            List<Goods> goods = goodsService.queryGoodsByDeptId(dept.getDeptId());
            dept.setProducts(goods);
        }
        return depts;
    }

    public static List<Dept> buildTree(List<Dept> deptList) {
        Map<Long, List<Dept>> deptByParentMap = deptList.stream().collect(Collectors.groupingBy(Dept::getParentId));
        deptList.forEach(dept -> dept.setChildren(deptByParentMap.get(dept.getDeptId())));
        return deptList.stream().filter(v -> v.getParentId().equals(0L)).collect(Collectors.toList());
    }


}
